package alf.mapping.view.touch;

import alf.mapping.dto.maps.Item;
import alf.mapping.dto.maps.Link;
import alf.mapping.view.Env;
import alf.mapping.view.activity.R;
import alf.mapping.view.visuals.Sprite;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemClock;
import android.view.MotionEvent;
import java.util.ArrayList;
import java.util.List;
import android.widget.ArrayAdapter;
import android.content.DialogInterface;

public class NavigatingTouchReactor extends AbstractTouchReactor 
{

	private boolean zooming;
	private Rect pos;
	

	private float zoomref;

	private ArrayList<Link> navegables;
	@Override
	protected boolean onTouch(MotionEvent event, Point punto, Rect puntogordo) {
		String msg = null;
		int index = event.getActionIndex();

        //      Env.debug("touchNavigating:2");
		float distancia = 0;
		switch (event.getActionMasked()) {
			case MotionEvent.ACTION_DOWN:
				onActionDownNavigating(puntogordo, punto);
				break;
			case MotionEvent.ACTION_POINTER_DOWN:
				onPointerDownNavigating(index, event);
				break;
			case MotionEvent.ACTION_MOVE:
				if (zooming) {
					onActionMoveZooming(punto, event, distancia);
				} else {
					onActionMoveScrolling(punto);
				}
				break;
			case MotionEvent.ACTION_UP:
				onActionUpNavigating(editor.getSelected(), punto);
				oldSel = editor.getSelected() == null ?null: editor.getSelected().get(0);
				oldSelTime = SystemClock.elapsedRealtime();
				break;
			case MotionEvent.ACTION_POINTER_UP:
				msg = "pointer.up";
				break;
		}
		if (msg != null) {      
			Env.setStatus(msg + "(" + index + ")");
		}
		return true;
	}

	private void onActionUpNavigating(List<Sprite> sel, Point punto) {
		if (sel != null) {
			if (sel.size() == 1) {
				Sprite selSprite = sel.get(0);
				Item item = selSprite.getItem();
				if (detectDoubleTap(selSprite)) {
					tryNavigation(selSprite);
				} else {
					Env.setStatus(R.string.msg_map_notif_selected, item.toString());
				}
			}
		} else {
			if (zooming) {
				zooming = false;
				Env.setStatus(R.string.msg_map_notif_zoom_changed, editor.getZoom());
			} else {
				pos.right = punto.x;
				pos.bottom = punto.y;
				editor.offset(pos.width(), pos.height());
				pos = new Rect();
				Env.setStatus(R.string.msg_map_notif_scroll_end, editor.getViewport());
			}
		}
	}

	private void onActionMoveScrolling(Point punto) {
		pos.right = punto.x;
		pos.bottom = punto.y;
		editor.offset((int)-(zoomFactor() * pos.width()), (int) -(zoomFactor() * pos.height()));

		pos.left = punto.x;
		pos.top = punto.y;
	}


	private void onActionMoveZooming(Point punto, MotionEvent event, float distancia) {
		pos.left = punto.x;
		pos.top = punto.y;
		if (event.getPointerCount() > 1) {
			pos.right = (int) event.getX(1);
			pos.bottom = (int) event.getY(1);
			distancia = distance(pos) * zoomFactor() ;
			float newzoom = editor.getZoom() * (distancia / zoomref);
			Env.setStatus(R.string.msg_map_notif_zooming, pos.toString(), distancia, zoomref , (int)newzoom);
			editor.setZoom((int)newzoom);
		}
	}

	private void onPointerDownNavigating(int index, MotionEvent event) {
		if (index == 1) {
			zooming = true;
			pos.right = (int) event.getX(index);
			pos.bottom = (int) event.getY(index);
			zoomref = distance(pos) * zoomFactor();
			Env.setStatus(R.string.msg_map_notif_zooming, pos.toString(), zoomref, zoomref , editor.getZoom());
		}
	}

	private void onActionDownNavigating(Rect puntogordo, Point punto) {
		Env.debug("action down");
		editor.select(spriteAtPos(puntogordo));
		pos = new Rect(punto.x, punto.y, punto.x, punto.y);
	}

	private void tryNavigation(Sprite sel){
		Item item = sel.getItem();
		
		navegables = new ArrayList<Link>();
		if (item.getLinks()!=null){
			for (Link k : item.getLinks()){
				if (k.isNavigable() && k.getDestination()!=null){
					navegables.add(k);
				}
			}
		}
		if (navegables.size()>0){
			if (navegables.size()==1){
				editor.followLink(navegables.get(0).getDestination());
				Env.setStatus(R.string.msg_map_notif_link, navegables.get(0).getDestination());
			} else {
				String[] nombres = new String[navegables.size()];
				for (int i=0;i<navegables.size();i++){
					nombres[i] = navegables.get(i).toString();
				}
				Env.showSelectDialog(this.ctx,
					"select destination",
					 new ArrayAdapter<String>(this.ctx, android.R.layout.simple_spinner_dropdown_item, nombres),
					new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface p1, int p) {
							onSelect(p);
						}
						
					 });
			}
		} else {
			Env.setStatus(R.string.msg_map_notif_link_empty, item.getName());    
		}
	}
	
	private void onSelect(int p){
	//	Env.toast(this.ctx,"select: "+p);
		editor.followLink(navegables.get(p).getDestination());
	}
	
}
